package com.boarsoft.boar.soagov.svc.biz;

import java.util.List;

import org.hibernate.query.Query;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.boarsoft.boar.entity.AppLib;
import com.boarsoft.boar.entity.LibInfo;
import com.boarsoft.boar.soagov.entity.AppSvc;
import com.boarsoft.boar.soagov.entity.LibSvc;
import com.boarsoft.boar.soagov.svc.SvcLibBiz;
import com.boarsoft.common.Util;
import com.boarsoft.common.dao.PagedResult;
import com.boarsoft.hibernate.biz.SimpleBizImpl;

@Component("svcLibBiz")
public class SvcLibBizImpl extends SimpleBizImpl implements SvcLibBiz {

	@Override
	@Transactional(readOnly = true)
	public PagedResult<LibInfo> list(String svcId, String key, String orderBy, int pageNo, int pageSize) {
		StringBuilder sb = new StringBuilder();
		sb.append(" from ").append(LibInfo.class.getName());
		sb.append(" a join a.svcs s where s.id='").append(svcId).append("'");
		if (Util.strIsNotEmpty(key)) {
			sb.append("and (a.code like '%").append(key);
			sb.append("%' or a.name like '%").append(key);
			sb.append("%')");
		}
		int total = dao.getTotal("select count(a.id)".concat(sb.toString()));
		if (Util.strIsNotEmpty(orderBy)) {
			sb.append(" order by a.").append(orderBy);
		} else {
			sb.append(" order by a.name");
		}
		List<LibInfo> lt = dao.list("select a".concat(sb.toString()), pageNo, pageSize);
		return new PagedResult<LibInfo>(total, lt, pageNo, pageSize);
	}

	@Override
	@Transactional(readOnly = true)
	public List<LibInfo> list(String svcId, short status) {
		StringBuilder sb = new StringBuilder();
		sb.append("select a from ").append(LibInfo.class.getName());
		sb.append(" a join a.svcs s where s.id='").append(svcId).append("'");
		sb.append(" and a.status=").append(status);
		return dao.list(sb.toString());
	}

	@Override
	@Transactional(readOnly = true)
	public List<LibInfo> list(String svcId) {
		StringBuilder sb = new StringBuilder();
		sb.append("select a from ").append(LibInfo.class.getName());
		sb.append(" a join a.svcs s where s.id='").append(svcId).append("'");
		return dao.list(sb.toString());
	}

	@Override
	@Transactional
	public void add(String libId, String[] svcIds) {
		StringBuilder sb = new StringBuilder().append("from ")//
				.append(LibSvc.class.getName()).append(" where libId=:libId and svcId=:svcId");
		// 关联库包与服务
		Query<LibSvc> lsQry = dao.createQuery(LibSvc.class, sb.toString());
		lsQry.setParameter("libId", libId);
		for (String svcId : svcIds) {
			lsQry.setParameter("svcId", svcId);
			LibSvc ls = lsQry.uniqueResult();
			if (ls == null) {
				ls = new LibSvc();
				ls.setSvcId(svcId);
				ls.setLibId(libId);
				dao.save(ls);
			}
		}
		// 查询依赖此库包的应用，关联这些应用与服务
		sb.setLength(0);
		sb.append("and libId='").append(libId).append("'");
		List<AppLib> alLt = dao.list(AppLib.class, sb.toString());
		// 检查应用与服务的关系
		sb.setLength(0);
		sb.append("from ").append(AppSvc.class.getName())//
				.append(" where appId=:appId and svcId=:svcId");
		Query<AppSvc> asQry = dao.createQuery(AppSvc.class, sb.toString());
		// 遍历所有应用，与服务建立关联
		for (AppLib al : alLt) {
			String appId = al.getAppId();
			lsQry.setParameter("appId", appId);
			for (String svcId : svcIds) {
				asQry.setParameter("svcId", svcId);
				AppSvc as = asQry.uniqueResult();
				if (as == null) {
					as = new AppSvc();
					as.setAppId(appId);
					as.setSvcId(svcId);
					// 依赖了此库包不代表就会暴露库包中的所有服务
					as.setStatus(AppSvc.STATUS_DISABLED);
					dao.save(as);
				} else {
					continue;
				}
			}
		}
	}

	@Override
	@Transactional(readOnly = true)
	public LibSvc get(String id) {
		return (LibSvc) dao.get(LibSvc.class, id);
	}

	@Override
	@Transactional
	public void remove(String libId, String[] svcIds) {
		StringBuilder sb = new StringBuilder()//
				.append("delete from ").append(LibSvc.class.getName())//
				.append(" where libId=:libId and svcId=:svcId");
		Query<?> q = dao.createQuery(sb.toString());
		q.setParameter("libId", libId);
		for (String svcId : svcIds) {
			q.setParameter("svcId", svcId);
			q.executeUpdate();
		}
	}

	@Override
	@Transactional
	public void delete(String svcId) {
		StringBuffer sb = new StringBuffer();
		sb.append("delete from  ").append(LibSvc.class.getName())//
				.append(" a where a.svc.id='").append(svcId).append("'");
		dao.executeUpdate(sb.toString());
	}
}